package arcane.object.gui.scroll;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.util.List;
import java.util.Vector;

import javax.swing.JScrollBar;

import org.lwjgl.opengl.GL11;

import arcane.object.game.sprite.MenuSprite;
import arcane.object.gui.DefaultButton;

public class ScrollBar extends MenuSprite {
	DefaultButton btn1;
	DefaultButton btn2;

	DefaultButton knob;

	// color of up/down buttons
	Color btnColor;
	// Whether bar runs left/right or up/down
	int orientation;

	// length of bar
	int length;

	// Pixels incremented when buttons are pressed
	int unitIncrement;

	// Pixels incremented when block is pressed
	int blockIncrement;

	List<AdjustmentListener> listeners;

	public static final int HORIZONTAL_BAR = 0, VERTICAL_BAR = 1;

	public static final JScrollBar NULL_PANE = new JScrollBar();

	public ScrollBar(int x, int y, int length, int orientation) {
		super(x, y);
		unitIncrement = 15;
		blockIncrement = 30;
		listeners = new Vector<AdjustmentListener>();
		this.length = length;
		btn1 = new CustomButton();
		btn2 = new CustomButton();
		btnColor = new Color(0f, 0f, .5f);
		color = Color.BLUE;
		btn1.setLocation(x, y);

		knob = new DefaultButton("");
		knob.setLocation(x, y);
		this.orientation = orientation;

		if (orientation == HORIZONTAL_BAR) {
			this.setSize(length, 16);
			btn2.setLocation(x + length - 16, y);
			knob.setSize(length, 16);
			btn2.setAngle(90);
			btn1.setAngle(270);
		} else if (orientation == VERTICAL_BAR) {
			this.setSize(16, length);
			knob.setSize(16, length);
			btn2.setLocation(x, y + length - 16);
			btn2.setAngle(180);
		}
	}

	public void mouseClicked(int x, int y) {
		// If horizontal orientation...
		AdjustmentEvent e = null;
		if (orientation == HORIZONTAL_BAR) {
			if (btn1.getBounds().contains(x, y))
				e = new AdjustmentEvent(NULL_PANE, HORIZONTAL_BAR,
						AdjustmentEvent.BLOCK_DECREMENT, unitIncrement, false);
			else if (btn2.getBounds().contains(x, y))
				e = new AdjustmentEvent(NULL_PANE, HORIZONTAL_BAR,
						AdjustmentEvent.BLOCK_INCREMENT, unitIncrement, false);
			else if (!knob.getBounds().contains(x, y)) {
				int type = knob.getX() < x ? AdjustmentEvent.BLOCK_DECREMENT
						: AdjustmentEvent.BLOCK_INCREMENT;
				e = new AdjustmentEvent(NULL_PANE, HORIZONTAL_BAR, type,
						blockIncrement, false);

			}
		}

		// If vertical orientation
		else {
			if (btn1.getBounds().contains(x, y))
				e = new AdjustmentEvent(NULL_PANE, VERTICAL_BAR,
						AdjustmentEvent.BLOCK_DECREMENT, unitIncrement, false);
			else if (btn2.getBounds().contains(x, y))
				e = new AdjustmentEvent(NULL_PANE, VERTICAL_BAR,
						AdjustmentEvent.BLOCK_INCREMENT, unitIncrement, false);
			else if (!knob.getBounds().contains(x, y)) {
				int type = knob.getY() < y ? AdjustmentEvent.BLOCK_DECREMENT
						: AdjustmentEvent.BLOCK_INCREMENT;
				e = new AdjustmentEvent(NULL_PANE, VERTICAL_BAR,
						AdjustmentEvent.BLOCK_INCREMENT, blockIncrement, false);
			}
		}
		if (e != null)
			this.fireAdjustmentPerformed(e);
	}

	public void addAdjustmentListener(AdjustmentListener listener) {
		listeners.add(listener);
	}

	public boolean removeAdjustmentListener(AdjustmentListener listener) {
		return listeners.remove(listener);
	}

	public void update(long time) {
		super.update(time);
		btn1.update(time);
		btn2.update(time);
		knob.update(time);
	}

	public void render(Graphics2D g, int x, int y) {
		g.setColor(this.color);
		g.fillRect(x, y, width, height);
		btn1.render(g);
		btn2.render(g);
	}

	protected void fireAdjustmentPerformed(AdjustmentEvent e) {
		for (int i = 0; i < listeners.size(); i++)
			listeners.get(i).adjustmentValueChanged(e);
	}

	private class CustomButton extends DefaultButton {
		public int degrees;
		private int buttonDim = 16;

		public CustomButton() {
			this(0, 0, 0);
		}

		public CustomButton(int x, int y, int degrees) {
			super("");
			setLocation(x, y);
			setWidth(buttonDim);
			setHeight(buttonDim);
		}

		/*
		 * public void mouseClicked(int x, int y) { if (isActive() &&
		 * isEnabled()) { int type; int id = orientation; if (this == btn1) type
		 * = AdjustmentEvent.UNIT_INCREMENT; else type =
		 * AdjustmentEvent.UNIT_DECREMENT; AdjustmentEvent e = new
		 * AdjustmentEvent(NULL_PANE, id, type, unitIncrement, false);
		 * fireAdjustmentPerformed(e); } }
		 */

		public void render(Graphics2D g) {
			if (isActive())
				render(g, originX, originY);
		}

		public void render(Graphics2D g, int x, int y) {
			g.setColor(btnColor);
			g.fillRect((int) getX(), (int) getY(), this.width, this.height);
			knob.render(g);
			setOpenGLColor(btnColor.darker().darker(), alpha);
			this.translate();
			GL11.glDisable(GL11.GL_TEXTURE_2D);
			{
				GL11.glBegin(GL11.GL_TRIANGLES); // Drawing Using Triangles
				GL11.glVertex2i(x + 8, y); // Top
				GL11.glVertex2i(x + 16, y + 8); // Bottom Left
				GL11.glVertex2f(x, y + 8); // Bottom Right
			}
			GL11.glEnd();
			GL11.glEnable(GL11.GL_TEXTURE_2D);
			GL11.glPopMatrix();
		}
	}
}